<?php
/**
 * Created by PhpStorm.
 * User: cc
 * Date: 2021/12/16
 * Time: 4:02 下午
 */

namespace app\live\controller\v2;

use app\aliyun\controller\AliyunRtc;
use app\chat\LiveMessage;
use app\common\cachemodel\live\LiveAnchorInfo;
use app\common\cachemodel\live\LiveAnswerAstroRecord;
use app\common\cachemodel\live\LiveAnswerDiceRecord;
use app\common\cachemodel\live\LiveAnswerTarotRecord;
use app\common\cachemodel\live\LiveAward;
use app\common\cachemodel\live\LiveAwardAcitveRecord;
use app\common\cachemodel\live\LiveCoupon;
use app\common\cachemodel\live\LiveCouponActiveRecord;
use app\common\cachemodel\live\LiveRecordingInfo;
use app\common\lib\Util;
use app\live\controller\LiveAuth;
use think\Cache;
use think\Db;
use XznsTools\cache\CacheManage;

/**
 * Class LiveActive
 * @package app\live\controller\v2
 */
class LiveActive extends LiveAuth
{

    /**
     * 停止直播
     */
    public function liveStop()
    {
        $liveRecordId = input('live_record_id/d', 0);

        if (!$liveRecordId)
        {
            return show(config('code.error'), '请求异常');
        }

        $record = (new LiveRecordingInfo())->getInfoById($liveRecordId, ['live_id', 'status', 'live_start_time']);

        if ($record && $record['live_id'] == $this->liveInfo['live_id'])
        {
            if ($record['status'] == 1)
            {
                $liveDuration = ceil(($this->request->time() - $record['live_start_time']) / 60);// 直播时长 分钟

                $res = (new LiveRecordingInfo())->updateData($liveRecordId, [
                    'status' => 2,
                    'live_duration' => $liveDuration,
                    'close_time' => $this->request->time(),
                    'close_use_type' => 1,
                    'close_uid' => 0
                ]);
                // 删除直播记录列表缓存
                CacheManage::getInstance()->setCacheConfig('live.live_recording', $this->liveInfo['live_id'])->rmCache('list');

                //移除订阅事件
                $result = (new AliyunRtc())->removeEventSubscribe($this->liveInfo['live_id']);
                if ($result['code'] !== 200)
                {
                    return show(config('code.error'), $result['msg']);
                }

                $taskId = Cache::get('live:startMPUTask:taskId:' . $this->liveInfo['live_id'], false);
                if ($taskId)
                {
                    // 关闭旧的        旁路直播
                    $result = (new AliyunRtc())->stopMPUTask($taskId);
                    if ($result['code'] !== 200)
                    {
                        return show(config('code.error'), $result['msg']);
                    }
                }

                // 删除连麦房间的频道
                (new AliyunRtc())->deleteRtcChannel($this->liveInfo['live_id']);
                if ($res)
                {
                    // 向用户发送关播消息
                    LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ALL, $this->liveInfo['live_id'], $this->liveInfo['live_id']), LiveMessage::MSG_TYPE_LIVE_STATUS, 1);
                    // 删除用户发送消息记录缓存
                    $redis = CacheManage::getInstance()->redisHandler;
                    $redis->del('live:send:msg:record:' . $this->liveInfo['live_id']);
                    // 批量 取消 解答 免费的申请
                    (new LiveAnswerAstroRecord())->cancelAnswerList($this->liveInfo['live_id'], $liveRecordId);
                    (new LiveAnswerDiceRecord())->cancelAnswerList($this->liveInfo['live_id'], $liveRecordId);
                    (new LiveAnswerTarotRecord())->cancelAnswerList($this->liveInfo['live_id'], $liveRecordId);

                    return show(config('code.success'), '直播已结束', [
                        'target' => 'local',
                        'link' => 'liver_page?page=live_detail&id=' . $liveRecordId
                    ]);
                } else
                {
                    return show(config('code.error'), '服务异常');
                }

            } else
            {
                return show(config('code.success'), '直播已结束', [
                    'target' => 'local',
                    'link' => 'liver_page?page=live_detail&id=' . $liveRecordId
                ]);
            }
        }

        return show(config('code.error'), '直播不存在');
    }

    /**
     * 卡券列表
     * @return \think\response\Json
     * @throws \Exception
     */
    public function couponList()
    {
        $anchor = (new LiveAnchorInfo())->getInfoById($this->liveInfo['live_id'], ['cids']);
        $coupon = (new LiveCoupon())->batchGetInfoByIds($anchor['cids']);
        $res = [];
        foreach ($coupon as $co)
        {
            if ($co['status'] == 1)
            {
                $res[] = [
                    'id' => $co['id'],
                    'img' => $co['img'],
                    'name' => $co['lcname'],
                    'type' => $co['type']
                ];
            }
        }
        return show(config('code.success'), '获取成功', $res);
    }

    /**
     * 发放卡券
     * @return \think\response\Json
     * @throws \app\common\lib\exception\ApiException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function sendCoupon()
    {
        $liveCid = input('cid/d', 0); // 直播优惠券ID
        $sendNum = input('send_num/d', 0);    // 发放数量
        $time = input('time/d', 0);
        $coupon_expire_time = input('coupon_expire_time/d', 0);//优惠券有效天数
        $userGroupType = input('user_group_type/d', 0);  //发放用户人群 1=>所有用户 2=>VIP用户

        if ($sendNum <= 0)
        {
            return show(config('code.error'), '数量必须大于0');
        }
        if ($coupon_expire_time <= 0)
        {
            return show(config('code.error'), '卡券有效期必须大于0');
        }
        if ($time <= 0)
        {
            return show(config('code.error'), '抢券时间必须大于0');
        }
        // 获取最新的直播记录ID
        $newRecordId = (new LiveRecordingInfo())->getNewestRecord($this->liveInfo['live_id']);
        $recordInfo = (new LiveRecordingInfo())->getInfoById($newRecordId, ['status']);
        if (!$recordInfo['status'])
        {
            return show(config('code.error'), '直播不存在！');
        }
        // 获取优惠券信息
        $couponInfo = Db::table('wechat_backup_07_18_14_43_00.live_coupon')->alias('lc')
            ->join('wechat_backup_07_18_14_43_00.zl_coupon_attr ca', 'ca.id=lc.cid')->where('lc.id', $liveCid)->where('lc.status', 1)
            ->field('ca.desc,lc.img,lc.cid')->find();

        if (!$couponInfo)
        {
            return show(config('code.error'), '优惠券数据异常');
        }
        $createTime = time();
        $adminInfo = $this->getUserAuth();
        // 写入数据
        $aid = (new LiveCouponActiveRecord())->insertGetId([
            'live_id' => $this->liveInfo['live_id'],
            'live_record_id' => $newRecordId,
            'user_group_type' => $userGroupType,
            'live_cid' => $liveCid,
            'total_num' => $sendNum,
            'send_num' => 0,
            'time' => $time,
            'coupon_expire_time' => $coupon_expire_time,
            'aid' => $adminInfo['aid'],
            'admin_type' => $adminInfo['admin_type'],
            'create_time' => $createTime
        ]);
        /**
         * array (
         * 'id' => '1',
         * 'cid' => '257',
         * 'name' => '卡券',
         * 'img' => '/uploads/20210831/fc92cafbd171ce1f74712c3d881a117c.png',
         * 'live_id' => '10185336',
         * 'live_record_id' => '2',
         * 'user_group_type' => '1',
         * 'live_cid' => '1',
         * 'total_num' => '10',
         * 'send_num' => '0',
         * 'time' => '3600',
         * 'create_time' => '1630400951',
         * 'coupon_expire_time' => '7',
         * )
         */

        $couponData = [
            'id' => $aid,
            'cid' => $couponInfo['cid'],
            'name' => $couponInfo['desc'],
            'img' => $couponInfo['img'],
            'live_id' => $this->liveInfo['live_id'],
            'live_record_id' => $newRecordId,
            'user_group_type' => $userGroupType,
            'live_cid' => $liveCid,
            'total_num' => $sendNum,
            'send_num' => 0,
            'time' => $time,
            'create_time' => $createTime,
            'coupon_expire_time' => $coupon_expire_time,
        ];
        // 缓存当前直播间 最新活动ID
        CacheManage::getInstance()->setCacheConfig('live.coupon_active')
            ->setCacheKeyDetail('new_active_id', $this->liveInfo['live_id'])
            ->setCacheType('string')
            ->setCache($aid, 'new_active_id', false);
        // 缓存当前活动信息
        CacheManage::getInstance()->setCacheConfig('live.coupon_active', $aid)->setCache($couponData, 'details', false);
        // 推送给所有人  此处需要排除主播
        LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ALL, $this->liveInfo['live_id'], $this->liveInfo['live_id']), LiveMessage::MSG_TYPE_POP_COUPON, [
            'id' => $aid,
            'title' => '优惠券',
            'img' => $couponInfo['img'],
            'name' => $couponInfo['desc'],
            'is_only_vip_show' => $userGroupType === 2 ? 1 : 0,
            'continue_sencond' => $time * 60
        ]);
        // 删除列表缓存
        CacheManage::getInstance()->setCacheConfig('live.coupon_active', $this->liveInfo['live_id'])->rmListPageCache();

        $jobData = [
            'type' => 'close_coupon_active',
            'coupon_acitve_id' => $aid,
        ];
        // 发送队列
        Util::queuePush('live_draw_a_lottery', $jobData, $time * 60 + 10);

        return show(config('code.success'), '发送成功');
    }

    /**
     * 奖品列表
     * @return \think\response\Json
     * @throws \Exception
     */
    public function prizeList()
    {
        $anchor = (new LiveAnchorInfo())->getInfoById($this->liveInfo['live_id'], ['pids']);
        $prize = (new LiveAward())->batchGetInfoByIds($anchor['pids']);
        $res = [];
        foreach ($prize as $pr)
        {
            if ($pr['status'] == 1)
            {
                $res[] = [
                    'id' => $pr['id'],
                    'type' => $pr['type'],
                    'name' => $pr['award_name'],
                ];
            }
        }
        array_multisort(array_column($res, 'id'), SORT_NUMERIC, SORT_DESC, $res);// 按 id 排序
        return show(config('code.success'), '获取成功', $res);
    }

    /**
     * 开始抽奖
     * @return \think\response\Json
     * @throws \app\common\lib\exception\ApiException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function sendPrize()
    {
        //抽奖记录
        $nowTime = time();
        $param['type'] = input('type/d', 0);
        $param['message'] = input('message/s', 0);
        $param['num'] = input('num/d', 0);
        $param['time'] = input('time/d', 0);
        $param['coupon_expire_time'] = input('coupon_expire_time/d', 0);
        $param['award_id'] = input('award_id/d', 0);
        $param['user_group_type'] = input('user_group_type/d', 0);
        $param['live_id'] = $this->liveInfo['live_id'];
        //点赞类型
        if ($param['type'] == 2)
        {
            ++$param['type'];
        }
        //指定弹幕类型
        if (isset($param['message']) && $param['message'])
        {
            $param['type'] = 2;
        }
        // 获取最新的直播记录ID
        $newRecordId = (new LiveRecordingInfo())->getNewestRecord($this->liveInfo['live_id']);
        $recordInfo = (new LiveRecordingInfo())->getInfoById($newRecordId, ['status']);
        if (!$recordInfo['status'])
        {
            return show(config('code.error'), '直播不存在！');
        }
        $param['live_record_id'] = $newRecordId;
        if (isset($param['num']))
        {
            if ($param['num'] <= 0)
            {
                return show(config('code.error'), '获奖数量必须大于0');
            }
            $param['num'] = (int)$param['num'];
        }
        if (isset($param['time']))
        {
            if ($param['time'] <= 0)
            {
                return show(config('code.error'), '开奖时间必须大于0');
            }
            $param['time'] = (int)$param['time'];
        }
        if (isset($param['coupon_expire_time']))
        {
            if ($param['coupon_expire_time'] <= 0)
            {
                return show(config('code.error'), '奖品有效期必须大于0');
            }
            $param['coupon_expire_time'] = (int)$param['coupon_expire_time'];
        }
        $param['status'] = 1;
        $param['create_time'] = $nowTime;
        $adminInfo = $this->getUserAuth();
        $param['aid'] = $adminInfo['aid'];
        $param['admin_type'] = $adminInfo['admin_type'];

        //获取当前直播间的最新开奖记录 create_time+time+30
        $newAwardRecord = (new LiveAwardAcitveRecord())->where(['live_id' => $this->liveInfo['live_id']])->order('id', 'DESC')->field('create_time,time')->find();
        $awardTime = $newAwardRecord['create_time'] + ($newAwardRecord['time'] * 60) + 31;
        //需等上次活动结束才可以新增
        if ($newAwardRecord && $nowTime < $awardTime)
        {
            $timeRange = $awardTime - $nowTime;
            return show(config('code.error'), "正在进行抽奖,还有{$timeRange}秒");
        }
        $awardInfo = (new LiveAward())->getInfoById($param['award_id'], ['name', 'type', 'cid', 'status']);
        if (!$awardInfo || (int)$awardInfo['status'] !== 1)
        {
            return show(config('code.error'), '奖品不存在，抽奖开启失败');
        }
        $activeId = (new LiveAwardAcitveRecord())->insertGetId($param);
        (new LiveAwardAcitveRecord())->initTable('live_award_active_user_' . $newRecordId); // 初始化抽奖用户表
        $activeJoinType = [ // 参与类型 1=>发送任意弹幕 2=>发送指定弹幕 3=>点赞
            1 => '发送任意弹幕',
            2 => '发送指定弹幕',
            3 => '点赞',
        ];

        $list = [
            [
                'title' => '参与方式：',
                'des_info' => [
                    'name' => $activeJoinType[$param['type']],
                    'target' => '',
                    'link' => '',
                    'is_show_left_time' => 0,
                ]
            ],
            [
                'title' => '',
                'des_info' => [
                    'name' => '',
                    'target' => '',
                    'link' => '',
                    'is_show_left_time' => 0,
                ]
            ],
            [
                'title' => '时间：',
                'des_info' => [
                    'name' => $param['time'] . '分钟',
                    'target' => '',
                    'link' => '',
                    'is_show_left_time' => 1,
                ]
            ],
            [
                'title' => '奖品：',
                'des_info' => [
                    'name' => $awardInfo['name'],
                    'target' => 'local',
                    'link' => $awardInfo['type'] == 1 ? "live_gift_position?id={$awardInfo['cid']}&need_auth=0" : 'empty',
                    'is_show_left_time' => 0,
                ]
            ],
            [
                'title' => '数量：',
                'des_info' => [
                    'name' => $param['num'] . '人',
                    'target' => '',
                    'link' => '',
                    'is_show_left_time' => 0,
                ]
            ],
        ];

        if ($param['type'] == 2)
        {// 指定弹幕
            $a = [
                [
                    'title' => '指定弹幕：',
                    'des_info' => [
                        'name' => $param['message'],
                        'target' => 'local',
                        'link' => 'live_comment?text=' . urlencode($param['message']) . '&need_auth=2',
                        'is_show_left_time' => 0,
                    ]
                ]
            ];
            array_splice($list, 1, 0, $a);
        }

        $awardData = [
            'id' => $activeId,
            'title' => '主播抽奖',
            'continue_second' => $param['time'] * 60,
            'list' => $list
        ];

        // 发送直播间消息
        LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ALL, $this->liveInfo['live_id'], $this->liveInfo['live_id']), LiveMessage::MSG_TYPE_POP_AWARD_START, $awardData);

        CacheManage::getInstance()->setCacheConfig('live.award_active', $this->liveInfo['live_id'])
            ->setCacheKeyDetail('now_active', $this->liveInfo['live_id'])->setCacheType('string')->setCacheTime($param['time'] * 60 + 30)->setCache($activeId, 'now_active', false);
        // 发送开奖队列
        Util::queuePush('live_draw_a_lottery', ['award_acitve_id' => $activeId], $param['time'] * 60);

        return show(config('code.success'), '抽奖开启成功');
    }
}
